__doc__ =   """ Function and classes for XYZRN format output.
            """
# This is a rather free implementation of the standard.

from AtomProperties import get_radius
from itertools import chain
from Einput import einput

XYZRN_COORDS_STRING = "%8.3f %8.3f %8.3f %8.3f %d %s\n"

def dict2xyzrn(d, radius_type ='united', forgiving =True):
    (x, y, z) = d['coords']
    r = get_radius(d, radius_type, forgiving)
    args = (x, y, z, r, 1, hash((x,y,z)))   # identical x,y,z coordinates will have the
    return XYZRN_COORDS_STRING % args       # same hash ... the opposite is not True!

def write_header(header):
    # Not implemented
    return []

def write_coords(atoms, radius_type ='united', forgiving =True):
    lines = []
    for (atom_id, atom) in atoms.sorted_items():
        if radius_type == 'united' and atom.element == ' H':
            continue
        fields = atom.get_dict()
        line = dict2xyzrn(fields, radius_type, forgiving)
        lines.append(line)
    return lines

def write_trailer(trailer):
    return []

class XYZRNWriter(object):

    def set_structure(self, entities, radius_type ='united', forgiving =True, header =None, trailer =None):
        self.structure = einput(entities, level ='A', name = 'structure')
        self.header = write_header(header)
        self.coords = write_coords(self.structure, radius_type, forgiving)
        self.trailer = write_trailer(trailer)

    def save(self, file):
        self.file = open(file, 'w')
        for part in chain(self.header, self.coords, self.trailer):
            self.file.writelines(part)
        self.file.close()

###EOF